/**
 * @brief 异步数据安全管理框架；对异步临界区数据安全管理设计模型
 * @version 1.0
 * @date 2023-10-28
 * 
 * @copyright Copyright (c) 2023
 * @attention 注意应用过程不要直接修改此文件实现，避免影响其他引用模块实现
 */

#ifndef __MVDEF_ASYNC_FW_H__
#define __MVDEF_ASYNC_FW_H__

#include "mvdef.h"
#include "mvos/mvos_apis.h"

/** 以下示例替换用宏，可以在需要“去掉”ASYN_POOL管理封套的场景下(去掉了mvdef_async_fw.h)，自行定义使用，可以减少代码修改 */
// #ifdef MV_ASYNC_POOL_DISABLE
// #define MV_ASYNC_UID_INVALID  NULL
// #define MV_ASYNC_UID2HDL(uid) uid
// #define MV_ASYNC_HDL2UID(hdl) hdl
// #endif
/************************************************
 *           关系池形式异步数据管理模型
 ************************************************
 * 典型应用设计实现流程：
 *   0. 关系池定义：   MV_ASYNC_POOL_DEF(name)
 *   *. 遇到部分编译器不支持 __attribute__((constructor)) 时，需要手动显式初始化关系池互斥锁 MV_ASYNC_POOL_MUTEX(name)
 *   1. 数据申请接口实现设计： 异步数据申请 -> mv_async_pool_uid_try_ins -> 异常处理 -> 完成
 *   2. 数据应用接口实现设计： (1)    分离式：mv_async_pool_uid_ref  -> 异常处理 -> 异步数据应用 -> mv_async_pool_uid_unref -> 完成
 *                           (2)    一体式: mv_async_pool_uid_try_do -> 异步数据应用 & 异常处理 -> 完成
 *                           (3-1) 一体式x: mv_async_pool_uid_try_ins_start -> {异步数据初始化} -> mv_async_pool_uid_try_ins_exception(可选) -> {异常处理} -> mv_async_pool_uid_try_ins_end(完成)
 *                           (3-2) 一体式x: mv_async_pool_uid_try_do_start -> {异步数据应用} -> mv_async_pool_uid_try_do_exception(可选) -> {异常处理} -> mv_async_pool_uid_try_do_end(完成)
 *   3. 数据释放接口实现设计： mv_async_pool_uid_drop -> 完成
 **/
/**
 * 需要使用超大池时，在引用本头文件上一行加上
 * #define MV_ASYNC_LARGE_POOL
 * 即可
 * 注意！！！如需以“指针句柄”形式无感透传到其他模块使用，需要注意当前系统地址类型长度，是否满足MV_ASYNC_UID长度要求
 **/
#ifdef  MV_ASYNC_LARGE_POOL
#define MV_ASYNC_UID     mv_u64_t
#define MV_ASYNC_HDLS_T  mv_u32_t
#define MV_ASYNC_GEN_T   mv_u32_t
#define UID_COMB(hpos, genid) ((((mv_u64_t)hpos)<<32) | genid)
#define HPOS(uid)  (uid>>32)
#define GENID(uid) (uid&0xffffffff)
#else
#define MV_ASYNC_UID     mv_u32_t
#define MV_ASYNC_HDLS_T  mv_u16_t
#define MV_ASYNC_GEN_T   mv_u16_t
#define UID_COMB(hpos, genid) ((((mv_u32_t)hpos)<<16) | genid)
#define HPOS(uid)  (uid>>16)
#define GENID(uid) (uid&0xffff)
#endif
#define MV_ASYNC_UID_INVALID  0  ///< 无效UID值，必定为0
#define MV_ASYNC_UID2HDL(uid) (unsign2vptr(uid))             ///< 以指针形式载体使用UID（通常用于模块对外以mv_vptr_t类型的句柄封装形式兼容使用）
#define MV_ASYNC_HDL2UID(hdl) (ptr2value(uid, MV_ASYNC_UID)) ///< 同上反向使用定义
/************************************************
 *           关系池形式异步数据管理模型
 ************************************************
 * 典型应用设计实现流程：
 *   0. 关系池定义：   MV_ASYNC_POOL_DEF(name)
 *   *. 遇到部分编译器不支持 __attribute__((constructor)) 时，需要手动显式初始化关系池互斥锁 MV_ASYNC_POOL_MUTEX(name)
 *   1. 数据申请接口实现设计： mv_async_pool_preins   -> 异常处理 -> 异步数据申请 -> mv_async_pool_uid_flush -> 完成
 *   2. 数据应用接口实现设计： mv_async_pool_uid_ref  -> 异常处理 -> 异步数据应用 -> mv_async_pool_uid_unref -> 完成
 *   3. 数据释放接口实现设计： mv_async_pool_uid_drop -> 完成
 * 缺点：
 *   1. 需要预先估算本模块最大分配异步数据数量
 *   2. 过大的估算值会造成一定程度的内存浪费
 * 结构消耗：
 *   1. 关系池基础消耗 16 / 32(L)
 *   2. 每8个预分配，额外消耗 12 / 16(L) + ADT
 *   3. 典型值：
 *      ADT = 4，预分配  16 =  272 字节
 *      ADT = 4，预分配  32 =  528 字节
 *      ADT = 4，预分配  64 = 1040 字节
 *      ADT = 4，预分配 128 = 2072 字节
 *      ADT = 4，预分配 256 = 4136 字节
 * 兼容性：
 *   1. 为了让模块对外表现完全兼容“使用/不使用”ASYN_POLL实现，请基于“普通（不使用）”ASYN_POLL的API设计准则进行对外接口设计
 *   2. 通常是mv_vptr_t的句柄形式对外封装使用
 *   3. 所以，清务必套用MV_ASYNC_UID2HDL和MV_ASYNC_HDL2UID，方便需求去掉ASYN_POLL时，利用宏定义开关进行控制，无需过多修改代码
 ************************************************/
/** 预分配关系池定义 */
/** sync_loop_time_ms: 若逻辑存在异步释放会出现死锁情况，建议使用同步释放方式编写 */
#define MV_ASYNC_POOL_DEF(name, ADT, hdl_max, f_release, sync_loop_time_ms) \
typedef mv_void_t(*pf_##name##_async_data_release)(ADT data);         \
typedef struct _async_pool_##name {                                   \
    MV_ASYNC_HDLS_T max;                                              \
    MV_ASYNC_HDLS_T used;                                             \
    /** 运行时临时数据 */                                              \
    MV_ASYNC_HDLS_T rare;            /** 记录最后分配位 */             \
    MV_ASYNC_HDLS_T free_min;        /** 记录最小空闲位 */             \
    mv_u32_t        u32_drop_check_interval; /** 同步drop轮询间隔（0=异步会分散处理; 0=无限）*/  \
    pf_##name##_async_data_release f_on_release;                      \
    mv_u32_t u32_slot_state[((hdl_max+31)/32)];                       \
    struct {                                                          \
        mv_u32_t       u32_ref;     /** 引用数 */                      \
        MV_ASYNC_GEN_T genid;       /** 防UID重入判断,每次自增 */       \
        mv_bool_t      bl_valid;    /** 是否有效 */                    \
        ADT            data;                                          \
    }hdls[hdl_max];                                                   \
}async_pool_##name##_t;                                               \
/** 静态关系池初始化 */                                                 \
static async_pool_##name##_t _gl_async_pool_##name = {.max = hdl_max, .used = 0, .rare = 0, .free_min = 0, .u32_drop_check_interval = sync_loop_time_ms, .f_on_release = f_release};  \
MVOS_MUTEX_INIT(_async_pool_##name) \
static __attribute__((unused)) mv_void_t async_pool_##name##_res_init() {if(_async_pool_##name##_mutex == NULL){mvos_mutex_init(&_async_pool_##name##_mutex);}}
/** 关系池名称 */
#define MV_ASYNC_POOL(name)       _gl_async_pool_##name
/** 关系池显式初始化调用（部分系统不支持constructor特性） */
#define MV_ASYNC_POOL_INIT(name)  async_pool_##name##_res_init()
/** 管理互斥锁名称 */
#define MV_ASYNC_POOL_MUTEX(name) _async_pool_##name##_mutex
/** ADT数据名称 */
#define MV_ASYNC_POLL_ADT_DATA(name, uid) (MV_ASYNC_POOL(name).hdls[HPOS(uid)].data)

/** 集中封装代码，不要直接调用(释放uid占用节点及数据) */
#define _uid_try_unreg(name, hpos) \
{\
    MV_ASYNC_HDLS_T _gpos; \
    mv_u8_t  _u8_bpos; \
    if ((MV_ASYNC_POOL(name).hdls[_hpos].bl_valid != MV_TRUE) && (MV_ASYNC_POOL(name).hdls[_hpos].u32_ref == 0)) {\
        if (MV_ASYNC_POOL(name).f_on_release) {\
            MV_ASYNC_POOL(name).f_on_release(MV_ASYNC_POOL(name).hdls[_hpos].data); \
        } \
        _gpos    = (_hpos>>5); \
        _u8_bpos = (_hpos&0x1f); \
        MV_ASYNC_POOL(name).u32_slot_state[_gpos] &= ~(1<<_u8_bpos); \
        MV_ASYNC_POOL(name).used--; \
        MV_ASYNC_POOL(name).free_min = (MV_ASYNC_POOL(name).free_min > hpos)? hpos : MV_ASYNC_POOL(name).free_min; \
    } \
}

/** 引用数增加 */
#define mv_async_pool_uid_ref(name, uid, pout_async_data, result) \
{\
    pout_async_data = NULL; \
    if (MV_ASYNC_POOL(name).hdls[HPOS(uid)].bl_valid != MV_TRUE) { \
        result = MV_EC_NOT_INIT; \
    } else if (MV_ASYNC_POOL(name).hdls[HPOS(uid)].genid != GENID(uid)) {\
        result = MV_EC_NOT_INIT; \
    } else { \
        mvos_mutex_lock(&MV_ASYNC_POOL_MUTEX(name)); \
        if (MV_ASYNC_POOL(name).hdls[HPOS(uid)].bl_valid != MV_TRUE) { \
            result = MV_EC_NOT_INIT; \
        } else { \
            MV_ASYNC_POOL(name).hdls[HPOS(uid)].u32_ref++; \
            pout_async_data = &MV_ASYNC_POOL(name).hdls[HPOS(uid)].data; \
            result = MV_EC_SUCCESS; \
        } \
        mvos_mutex_unlock(&MV_ASYNC_POOL_MUTEX(name)); \
    } \
}

/** 引用数减少（带0引用释放） */
#define mv_async_pool_uid_unref(name, uid) \
{\
    MV_ASYNC_HDLS_T _hpos = HPOS(uid); \
    if (MV_ASYNC_POOL(name).hdls[_hpos].genid == GENID(uid)) { \
        mvos_mutex_lock(&MV_ASYNC_POOL_MUTEX(name)); \
        MV_ASYNC_POOL(name).hdls[_hpos].u32_ref--; \
        if (MV_ASYNC_POOL(name).u32_drop_check_interval == 0) { \
            _uid_try_unreg(name, _hpos) \
        } \
        mvos_mutex_unlock(&MV_ASYNC_POOL_MUTEX(name)); \
    } \
}
/********************************/
/** 专用于try...exception接口(非0表示各自定义异常号；均会跳转到exception_do代码段调用处理) ; 禁止直接调用break关键字打断try过程!!! */
#define MV_ASYNC_EXCEPTION_RAISE(s32_except) {_s32_async_exp_line=__LINE__; _s32_async_exception=s32_except; goto _mv_async_pool_uid_try_out;}
/** 配套用于在try...exception接口内，读取当前异常号 */
#define _mv_async_exception_line              (_s32_async_exp_line)
#define _mv_async_exception_code              (_s32_async_exception)
/** 管理池节点预占用标记
 * (try内，需要尽快调用MV_ASYNC_POLL_ADT_DATA对ADT进行赋值，exception得时候能自动关联到release接口释放）
 *（try ins内，不能使用任何try...excetion接口，因为此时句柄还未完成初始化，会导致你的其他try代码逻辑无效)
 */
/////////////////////////////////////////////////////////////////
/** 一体化尝试添加(try和exception一体封装，注意__LINE__无法正常反映真实行号) */
/////////////////////////////////////////////////////////////////
#define mv_async_pool_uid_try_ins(name, out_uid, _s32_try_ret, try_do, exception_do) \
{\
    MV_ASYNC_HDLS_T _hpos; \
    MV_ASYNC_HDLS_T _gpos; \
    __attribute__((unused)) mv_s32_t  _s32_async_exp_line  = 0; \
    mv_s32_t  _s32_async_exception = 0; \
    mv_u8_t   _u8_bmax; \
    mv_u8_t   _u8_bpos; \
    mv_bool_t _bl_break = MV_FALSE; \
    _s32_try_ret = MV_EC_FAILED; \
    mvos_mutex_lock(&MV_ASYNC_POOL_MUTEX(name)); \
    if (MV_ASYNC_POOL(name).used < MV_ASYNC_POOL(name).max) { \
        MV_ASYNC_POOL(name).used++; \
        /** 存在free记录，直接使用 */ \
        if (MV_ASYNC_POOL(name).free_min > 0) { \
            MV_ASYNC_POOL(name).rare     = MV_ASYNC_POOL(name).free_min; \
            MV_ASYNC_POOL(name).free_min = 0; \
            MV_ASYNC_POOL(name).hdls[MV_ASYNC_POOL(name).free_min].genid++; \
            MV_ASYNC_POOL(name).hdls[MV_ASYNC_POOL(name).free_min].u32_ref = 1; \
            if (MV_ASYNC_POOL(name).hdls[MV_ASYNC_POOL(name).free_min].genid == 0) {MV_ASYNC_POOL(name).hdls[MV_ASYNC_POOL(name).free_min].genid = 1;} \
            out_uid = UID_COMB(MV_ASYNC_POOL(name).free_min, MV_ASYNC_POOL(name).hdls[MV_ASYNC_POOL(name).free_min].genid); \
        } else { \
            if (MV_ASYNC_POOL(name).rare >= MV_ASYNC_POOL(name).max) {MV_ASYNC_POOL(name).rare = 0;} \
            _gpos    = (MV_ASYNC_POOL(name).rare>>5); \
            _u8_bpos = (MV_ASYNC_POOL(name).rare&0x1f); \
            for (; _gpos < (sizeof(MV_ASYNC_POOL(name).u32_slot_state)/sizeof(MV_ASYNC_POOL(name).u32_slot_state[0])); _gpos++) { \
                _u8_bmax = ((MV_ASYNC_POOL(name).rare+32) > (MV_ASYNC_POOL(name).max))? (MV_ASYNC_POOL(name).max-(_gpos<<5)) : 32; \
                for (; _u8_bpos < _u8_bmax; _u8_bpos++, MV_ASYNC_POOL(name).rare++) { \
                    if (MV_ASYNC_POOL(name).u32_slot_state[_gpos]&(1<<_u8_bpos)) {continue;} \
                    /** 找到空闲位置，标记，换算下标 */ \
                    MV_ASYNC_POOL(name).u32_slot_state[_gpos] |= (1<<_u8_bpos); \
                    _hpos  = (_gpos<<5) + _u8_bpos; \
                    MV_ASYNC_POOL(name).hdls[_hpos].genid++; \
                    MV_ASYNC_POOL(name).hdls[_hpos].u32_ref = 1; \
                    if (MV_ASYNC_POOL(name).hdls[_hpos].genid == 0) {MV_ASYNC_POOL(name).hdls[_hpos].genid = 1;} \
                    out_uid = UID_COMB(_hpos, MV_ASYNC_POOL(name).hdls[_hpos].genid); \
                    _bl_break = MV_TRUE; \
                    MV_ASYNC_POOL(name).rare++; \
                    break; \
                } \
                if (_bl_break == MV_TRUE) { \
                    break; \
                } \
                _u8_bpos = 0; \
            } \
        } \
    } \
    /** do try action */ \
    _hpos = HPOS(out_uid); \
    if (out_uid != MV_ASYNC_UID_INVALID) { \
        _s32_try_ret = MV_EC_SUCCESS; \
        do {try_do;} while (0); \
        _mv_async_pool_uid_try_out:\
        if (_s32_async_exception != 0) { \
            do{exception_do;}while(0); \
            MV_ASYNC_POOL(name).hdls[_hpos].bl_valid = MV_FALSE; \
            MV_ASYNC_POOL(name).hdls[_hpos].u32_ref = 0; \
            _uid_try_unreg(name, _hpos) \
            out_uid = MV_ASYNC_UID_INVALID; \
        } else { \
            MV_ASYNC_POOL(name).hdls[_hpos].bl_valid = MV_TRUE; \
        } \
    } \
    /** do end */ \
    mvos_mutex_unlock(&MV_ASYNC_POOL_MUTEX(name)); \
}

/** 标记为即将丢弃 */
#define mv_async_pool_uid_drop(name, uid, act_before_drop) \
{\
    MV_ASYNC_HDLS_T _hpos = HPOS(uid); \
    if ((uid != MV_ASYNC_UID_INVALID) \
    &&  (MV_ASYNC_POOL(name).hdls[_hpos].genid == GENID(uid)) \
    &&  (MV_ASYNC_POOL(name).hdls[_hpos].bl_valid == MV_TRUE)) { \
        mvos_mutex_lock(&MV_ASYNC_POOL_MUTEX(name)); \
        MV_ASYNC_POOL(name).hdls[_hpos].bl_valid = MV_FALSE; \
        MV_ASYNC_POOL(name).hdls[_hpos].u32_ref--; \
        act_before_drop; \
        mvos_mutex_unlock(&MV_ASYNC_POOL_MUTEX(name)); \
        if (MV_ASYNC_POOL(name).u32_drop_check_interval > 0) { \
            while (1) { \
                if (MV_ASYNC_POOL(name).hdls[_hpos].u32_ref == 0) { \
                    _uid_try_unreg(name, _hpos) \
                    break; \
                }; \
                mvos_msleep(MV_ASYNC_POOL(name).u32_drop_check_interval); \
            } \
        } else { \
            _uid_try_unreg(name, _hpos) \
        } \
    } \
}

/////////////////////////////////////////////////////////////////
/** 一体化引用过程(try和exception一体封装，注意__LINE__无法正常反映真实行号) */
/////////////////////////////////////////////////////////////////
#define mv_async_pool_uid_try_do(name, uid, s32_try_ret, try_do, exception_do) \
{\
    __attribute__((unused)) mv_s32_t _s32_async_exp_line  = 0; \
    mv_s32_t _s32_async_exception  = 0; \
    MV_ASYNC_HDLS_T _hpos = HPOS(uid); \
    if (uid == MV_ASYNC_UID_INVALID) {\
        s32_try_ret = MV_EC_NOT_INIT; \
    } else if (MV_ASYNC_POOL(name).hdls[_hpos].bl_valid != MV_TRUE) { \
        s32_try_ret = MV_EC_NOT_INIT; \
    } else if (MV_ASYNC_POOL(name).hdls[_hpos].genid != GENID(uid)) {\
        s32_try_ret = MV_EC_NOT_INIT; \
    } else { \
        mvos_mutex_lock(&MV_ASYNC_POOL_MUTEX(name)); \
        if (MV_ASYNC_POOL(name).hdls[_hpos].bl_valid != MV_TRUE) { \
            s32_try_ret = MV_EC_NOT_INIT; \
        } else { \
            MV_ASYNC_POOL(name).hdls[_hpos].u32_ref++; \
            s32_try_ret = MV_EC_SUCCESS; \
        } \
        mvos_mutex_unlock(&MV_ASYNC_POOL_MUTEX(name)); \
    } \
    if (s32_try_ret == MV_EC_SUCCESS) {\
        do{try_do;}while(0); \
        _mv_async_pool_uid_try_out:\
        if (_s32_async_exception != 0) { \
            do{exception_do;}while(0); \
        }\
        mvos_mutex_lock(&MV_ASYNC_POOL_MUTEX(name)); \
        MV_ASYNC_POOL(name).hdls[_hpos].u32_ref--; \
        if (MV_ASYNC_POOL(name).u32_drop_check_interval == 0) { \
            _uid_try_unreg(name, _hpos) \
        } \
        mvos_mutex_unlock(&MV_ASYNC_POOL_MUTEX(name)); \
    } \
}

/////////////////////////////////////////////////////////////////
/****************************************************************
 * 一体化尝试添加(try和exception拆分宏，中间写do代码块和exception代码块；
 * 此方法__LINE__能正常使用; 所有代码块必须使用{}进行块封装
 ****************************************************************/
/////////////////////////////////////////////////////////////////
#define mv_async_pool_uid_try_ins_start(name, out_uid, _s32_try_ret) \
{                                                                    \
    MV_ASYNC_HDLS_T _hpos;                                           \
    MV_ASYNC_HDLS_T _gpos;                                           \
    __attribute__((unused)) mv_s32_t  _s32_async_exp_line  = 0;      \
    mv_s32_t  _s32_async_exception = 0;                              \
    mv_u8_t   _u8_bmax;                                              \
    mv_u8_t   _u8_bpos;                                              \
    mv_bool_t _bl_break = MV_FALSE;                                  \
    _s32_try_ret = MV_EC_FAILED;                                     \
    mvos_mutex_lock(&MV_ASYNC_POOL_MUTEX(name));                     \
    if (MV_ASYNC_POOL(name).used < MV_ASYNC_POOL(name).max) {        \
        MV_ASYNC_POOL(name).used++;                                  \
        /** 存在free记录，直接使用 */                                  \
        if (MV_ASYNC_POOL(name).free_min > 0) {                      \
            MV_ASYNC_POOL(name).rare     = MV_ASYNC_POOL(name).free_min;            \
            MV_ASYNC_POOL(name).free_min = 0;                        \
            MV_ASYNC_POOL(name).hdls[MV_ASYNC_POOL(name).free_min].genid++;         \
            MV_ASYNC_POOL(name).hdls[MV_ASYNC_POOL(name).free_min].u32_ref = 1;     \
            if (MV_ASYNC_POOL(name).hdls[MV_ASYNC_POOL(name).free_min].genid == 0) {MV_ASYNC_POOL(name).hdls[MV_ASYNC_POOL(name).free_min].genid = 1;} \
            out_uid = UID_COMB(MV_ASYNC_POOL(name).free_min, MV_ASYNC_POOL(name).hdls[MV_ASYNC_POOL(name).free_min].genid); \
        } else {                                                      \
            if (MV_ASYNC_POOL(name).rare >= MV_ASYNC_POOL(name).max) {MV_ASYNC_POOL(name).rare = 0;} \
            _gpos    = (MV_ASYNC_POOL(name).rare>>5);                 \
            _u8_bpos = (MV_ASYNC_POOL(name).rare&0x1f);               \
            for (; _gpos < (sizeof(MV_ASYNC_POOL(name).u32_slot_state)/sizeof(MV_ASYNC_POOL(name).u32_slot_state[0])); _gpos++) { \
                _u8_bmax = ((MV_ASYNC_POOL(name).rare+32) > (MV_ASYNC_POOL(name).max))? (MV_ASYNC_POOL(name).max-(_gpos<<5)) : 32; \
                for (; _u8_bpos < _u8_bmax; _u8_bpos++, MV_ASYNC_POOL(name).rare++) {        \
                    if (MV_ASYNC_POOL(name).u32_slot_state[_gpos]&(1<<_u8_bpos)) {continue;} \
                    /** 找到空闲位置，标记，换算下标 */                  \
                    MV_ASYNC_POOL(name).u32_slot_state[_gpos] |= (1<<_u8_bpos);       \
                    _hpos  = (_gpos<<5) + _u8_bpos;                    \
                    MV_ASYNC_POOL(name).hdls[_hpos].genid++;           \
                    MV_ASYNC_POOL(name).hdls[_hpos].u32_ref = 1;       \
                    if (MV_ASYNC_POOL(name).hdls[_hpos].genid == 0) {MV_ASYNC_POOL(name).hdls[_hpos].genid = 1;} \
                    out_uid = UID_COMB(_hpos, MV_ASYNC_POOL(name).hdls[_hpos].genid); \
                    _bl_break = MV_TRUE;                               \
                    MV_ASYNC_POOL(name).rare++;                        \
                    break;                                             \
                }                                                      \
                if (_bl_break == MV_TRUE) {                            \
                    break;                                             \
                }                                                      \
                _u8_bpos = 0;                                          \
            }                                                          \
        }                                                              \
    }                                                                  \
    /** do try action */                                               \
    _hpos = HPOS(out_uid);                                             \
    do {                                                               \
        if (out_uid != MV_ASYNC_UID_INVALID) {                         \
            _s32_try_ret = MV_EC_SUCCESS;

#define mv_async_pool_uid_try_ins_exception(name)                      \
            _mv_async_pool_uid_try_out:                                \
            if (_s32_async_exception != 0)

#define mv_async_pool_uid_try_ins_end(name, out_uid)                   \
            if (_s32_async_exception != 0) {                           \
                MV_ASYNC_POOL(name).hdls[_hpos].bl_valid = MV_FALSE;   \
                MV_ASYNC_POOL(name).hdls[_hpos].u32_ref = 0;           \
                _uid_try_unreg(name, _hpos)                            \
                out_uid = MV_ASYNC_UID_INVALID;                        \
                break;                                                 \
            }                                                          \
            MV_ASYNC_POOL(name).hdls[_hpos].bl_valid = MV_TRUE;        \
        }                                                              \
    } while(0);                                                        \
    /** do end */                                                      \
    mvos_mutex_unlock(&MV_ASYNC_POOL_MUTEX(name));                     \
}

/////////////////////////////////////////////////////////////////
/****************************************************************
 * 一体化引用过程(try和exception拆分宏，中间写do代码块和exception代码块；
 * 此方法__LINE__能正常使用; 所有代码块必须使用{}进行块封装
 ****************************************************************/
/////////////////////////////////////////////////////////////////
#define mv_async_pool_uid_try_do_start(name, uid, s32_try_ret)         \
{                                                                      \
    __attribute__((unused)) mv_s32_t _s32_async_exp_line  = 0;         \
    __attribute__((unused)) mv_s32_t _s32_async_exception = 0;         \
    MV_ASYNC_HDLS_T _hpos = HPOS(uid);                                 \
    if (uid == MV_ASYNC_UID_INVALID) {                                 \
        s32_try_ret = MV_EC_NOT_INIT;                                  \
    } else if (MV_ASYNC_POOL(name).hdls[_hpos].bl_valid != MV_TRUE) {  \
        s32_try_ret = MV_EC_NOT_INIT;                                  \
    } else if (MV_ASYNC_POOL(name).hdls[_hpos].genid != GENID(uid)) {  \
        s32_try_ret = MV_EC_NOT_INIT;                                  \
    } else {                                                           \
        mvos_mutex_lock(&MV_ASYNC_POOL_MUTEX(name));                   \
        if (MV_ASYNC_POOL(name).hdls[_hpos].bl_valid != MV_TRUE) {     \
            s32_try_ret = MV_EC_NOT_INIT;                              \
        } else {                                                       \
            MV_ASYNC_POOL(name).hdls[_hpos].u32_ref++;                 \
            s32_try_ret = MV_EC_SUCCESS;                               \
        }                                                              \
        mvos_mutex_unlock(&MV_ASYNC_POOL_MUTEX(name));                 \
    }                                                                  \
    if (s32_try_ret == MV_EC_SUCCESS) {

#define mv_async_pool_uid_try_do_exception(name)                       \
    }                                                                  \
    _mv_async_pool_uid_try_out:                                        \
    if (_s32_async_exception != 0) {

#define mv_async_pool_uid_try_do_end(name)                             \
    }                                                                  \
    mvos_mutex_lock(&MV_ASYNC_POOL_MUTEX(name));                       \
    MV_ASYNC_POOL(name).hdls[_hpos].u32_ref--;                         \
    if (MV_ASYNC_POOL(name).u32_drop_check_interval == 0) {            \
        _uid_try_unreg(name, _hpos)                                    \
    }                                                                  \
    mvos_mutex_unlock(&MV_ASYNC_POOL_MUTEX(name));                     \
}
#endif
